home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / recvfax / submit.c < prev   
C/C++ Source or Header  |  1994-08-01  |  8KB  |  293 lines

  1. /*    $Header: /usr/people/sam/fax/recvfax/RCS/submit.c,v 1.24 1994/04/04 18:25:18 sam Rel $
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "defs.h"
  26.  
  27. #include <fcntl.h>
  28. #include <sys/file.h>
  29. #include <dirent.h>
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32.  
  33. static    char qfile[1024];
  34. static    FILE* qfd = NULL;
  35.  
  36. static    int getSequenceNumber();
  37. static    void coverProtocol(int version, int seqnum);
  38. static    void setupData(int seqnum);
  39. static    void cleanupJob();
  40. static    u_long cvtTimeOrDie(const char* spec, struct tm* ref, const char* what);
  41.  
  42. void
  43. submitJob(const char* modem, char* otag)
  44. {
  45.     u_long tts = 0;
  46.  
  47.     sprintf(qfile, "%s/q%d", FAX_SENDDIR, seqnum = getSequenceNumber());
  48.     qfd = fopen(qfile, "w");
  49.     if (qfd == NULL) {
  50.     syslog(LOG_ERR, "%s: Can not create qfile: %m", qfile);
  51.     sendError("Can not create qfile \"%s\".", qfile);
  52.     cleanupJob();
  53.     }
  54.     flock(fileno(qfd), LOCK_EX);
  55.     fprintf(qfd, "modem:%s\n", modem);
  56.     for (;;) {
  57.     if (!getCommandLine())
  58.         cleanupJob();
  59.     if (isCmd("end") || isCmd(".")) {
  60.         setupData(seqnum);
  61.         break;
  62.     }
  63.     if (isCmd("sendAt")) {
  64.         tts = cvtTimeOrDie(tag, &now, "time-to-send");
  65.     } else if (isCmd("killtime")) {
  66.         fprintf(qfd, "%s:%lu\n", line, cvtTimeOrDie(tag, &now, "kill-time"));
  67.     } else if (isCmd("cover")) {
  68.         coverProtocol(atoi(tag), seqnum);
  69.     } else
  70.         fprintf(qfd, "%s:%s\n", line, tag);    /* XXX check info */
  71.     }
  72.     fprintf(qfd, "tts:%lu\n", tts);
  73.     fclose(qfd), qfd = NULL;
  74.     if (!notifyServer(modem, "S%s", qfile))
  75.     sendError("Warning, no server appears to be running.");
  76.     sendClient("job", "%d", seqnum);
  77. }
  78.  
  79. static u_long
  80. cvtTimeOrDie(const char* spec, struct tm* ref, const char* what)
  81. {
  82.     u_long when;
  83.  
  84.     if (!cvtTime(spec, ref, &when, what)) {
  85.     cleanupJob();
  86.     /*NOTREACHED*/
  87.     }
  88.     return (when);
  89. }
  90.  
  91. static void
  92. coverProtocol(int version, int seqnum)
  93. {
  94.     char template[1024];
  95.     FILE* fd;
  96.  
  97.     sprintf(template, "%s/doc%d.cover", FAX_DOCDIR, seqnum);
  98.     fd = fopen(template, "w");
  99.     if (fd == NULL) {
  100.     syslog(LOG_ERR, "%s: Could not create cover sheet file: %m",
  101.         template);
  102.     sendError("Could not create cover sheet file \"%s\".", template);
  103.     cleanupJob();
  104.     }
  105.     while (getCommandLine()) {
  106.     if (isCmd("..")) {
  107.         fprintf(qfd, "postscript: %s\n", template);
  108.         break;
  109.     }
  110.     fprintf(fd, "%s\n", tag);
  111.     }
  112.     fclose(fd);
  113. }
  114.  
  115. static void
  116. setupData(int seqnum)
  117. {
  118.     int i;
  119.  
  120.     for (i = 0; i < nDataFiles; i++) {
  121.     char doc[1024];
  122.     sprintf(doc, "%s/doc%d.%d", FAX_DOCDIR, seqnum, i);
  123.     if (link(dataFiles[i], doc) < 0) {
  124.         syslog(LOG_ERR, "Can not link document \"%s\": %m", doc);
  125.         sendError("Problem setting up document files.");
  126.         while (--i >= 0) {
  127.         sprintf(doc, "%s/doc%d.%d", FAX_DOCDIR, seqnum, i);
  128.         unlink(doc);
  129.         }
  130.         cleanupJob();
  131.         /*NOTREACHED*/
  132.     }
  133.     fprintf(qfd, "%s:%s\n",
  134.         fileTypes[i] == TYPE_TIFF ? "tiff" : "postscript", doc);
  135.     }
  136.     for (i = 0; i < nPollIDs; i++)
  137.     fprintf(qfd, "poll:%s\n", pollIDs[i]);
  138. }
  139.  
  140. static void
  141. getData(int type, long cc)
  142. {
  143.     long total;
  144.     int dfd;
  145.     char template[80];
  146.  
  147.     if (cc <= 0)
  148.     return;
  149.     sprintf(template, "%s/sndXXXXXX", FAX_TMPDIR);
  150.     dfd = mkstemp(template);
  151.     if (dfd < 0) {
  152.     syslog(LOG_ERR, "%s: Could not create data temp file: %m", template);
  153.     sendError("Could not create data temp file.");
  154.     cleanupJob();
  155.     }
  156.     newDataFile(template, type);
  157.     total = 0;
  158.     while (cc > 0) {
  159.     char buf[4096];
  160.     int n = MIN(cc, sizeof (buf));
  161.     if (fread(buf, n, 1, stdin) != 1) {
  162.         protocolBotch( "not enough data received: %u of %u bytes.",
  163.         total, total+cc);
  164.         cleanupJob();
  165.     }
  166.     if (write(dfd, buf, n) != n) {
  167.         extern int errno;
  168.         sendAndLogError("Error writing data file: %s.", strerror(errno));
  169.         cleanupJob();
  170.     }
  171.     cc -= n;
  172.     total += n;
  173.     }
  174.     close(dfd);
  175.     if (debug)
  176.     syslog(LOG_DEBUG, "%s: %d-byte %s", template, total,
  177.         type == TYPE_TIFF ? "TIFF image" : "PostScript document");
  178. }
  179.  
  180. void
  181. getTIFFData(const char* modemname, char* tag)
  182. {
  183.     getData(TYPE_TIFF, atol(tag));
  184. }
  185.  
  186. void
  187. getPostScriptData(const char* modemname, char* tag)
  188. {
  189.     getData(TYPE_POSTSCRIPT, atol(tag));
  190. }
  191.  
  192. void
  193. getDataOldWay(const char* modemname, char* tag)
  194. {
  195.     long cc;
  196.     int type;
  197.  
  198.     if (isTag("tiff"))
  199.     type = TYPE_TIFF;
  200.     else if (isTag("postscript"))
  201.     type = TYPE_POSTSCRIPT;
  202.     else {
  203.     sendAndLogError("Can not handle \"%s\"-type data", tag);
  204.     cleanupJob();
  205.     /*NOTREACHED*/
  206.     }
  207.     if (fread(&cc, sizeof (long), 1, stdin) != 1) {
  208.     protocolBotch("no data byte count.");
  209.     cleanupJob();
  210.     }
  211.     getData(type, cc);
  212. }
  213.  
  214. void
  215. newDataFile(char* filename, int type)
  216. {
  217.     int l;
  218.     char* cp;
  219.  
  220.     if (++nDataFiles == 1) {
  221.     dataFiles = (char**)malloc(sizeof (char*));
  222.     fileTypes = (int*)malloc(sizeof (int));
  223.     } else {
  224.     dataFiles = (char**)realloc(dataFiles, nDataFiles * sizeof (char*));
  225.     fileTypes = (int*)realloc(fileTypes, nDataFiles * sizeof (int));
  226.     }
  227.     l = strlen(filename)+1;
  228.     cp = (char*)malloc(l);
  229.     memcpy(cp, filename, l);
  230.     dataFiles[nDataFiles-1] = cp;
  231.     fileTypes[nDataFiles-1] = type;
  232. }
  233.  
  234. void
  235. newPollID(const char* modemname, char* pid)
  236. {
  237.     int l;
  238.     char* cp;
  239.  
  240.     if (++nPollIDs == 1)
  241.     pollIDs = (char**)malloc(sizeof (char*));
  242.     else
  243.     pollIDs = (char**)realloc(pollIDs, nPollIDs * sizeof (char*));
  244.     l = strlen(pid)+1;
  245.     cp = (char*)malloc(l);
  246.     memcpy(cp, pid, l);
  247.     pollIDs[nPollIDs-1] = cp;
  248. }
  249.  
  250. static void
  251. cleanupJob()
  252. {
  253.     int i;
  254.  
  255.     for (i = 0; i < nDataFiles; i++)
  256.     unlink(dataFiles[i]);
  257.     { char template[1024];
  258.       sprintf(template, "%s/doc%d.cover", FAX_DOCDIR, seqnum);
  259.       unlink(template);
  260.     }
  261.     if (qfd)
  262.     unlink(qfile);
  263.     done(1, "EXIT");
  264. }
  265.  
  266. static int
  267. getSequenceNumber()
  268. {
  269.     int seqnum;
  270.     int fd;
  271.  
  272.     fd = open(FAX_SEQF, O_CREAT|O_RDWR, 0644);
  273.     if (fd < 0) {
  274.     syslog(LOG_ERR, "%s: open: %m", FAX_SEQF);
  275.     sendError("Problem opening sequence number file.");
  276.     done(-2, "EXIT");
  277.     }
  278.     flock(fd, LOCK_EX);
  279.     seqnum = 1;
  280.     if (read(fd, line, sizeof (line)) > 0)
  281.     seqnum = atoi(line);
  282.     sprintf(line, "%d", seqnum < 9999 ? seqnum+1 : 1);
  283.     lseek(fd, 0, SEEK_SET);
  284.     if (write(fd, line, strlen(line)) != strlen(line)) {
  285.     sendAndLogError("Problem updating sequence number file.");
  286.     done(-3, "EXIT");
  287.     }
  288.     close(fd);            /* implicit unlock */
  289.     if (debug)
  290.     syslog(LOG_DEBUG, "seqnum %d", seqnum);
  291.     return (seqnum);
  292. }
  293.